﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LevenBlog.Core.Data;
using LevenBlog.Core.Entities;
using LevenBlog.Core.Utils;
using LevenBlog.Core.Cache;

namespace LevenBlog.Core.Service {
    public static class Category {
        private static readonly string cacheName = "levenblog_servicecache_category";

        public static IList<lb_category> Get(IDbProvider provider) {
            //if (categoryList == null) {
            //    lock (lockObject) {
            //        if (categoryList == null) {
            //            categoryList = (ProviderManager.Factory.Category.Get(provider) as List<lb_category>).AsReadOnly();
            //        }
            //    }
            //}
            //return categoryList;
            IList<lb_category> find = ObjectCache.Get<IList<lb_category>>(cacheName);
            if (find == null) {
                find = ProviderManager.Factory.Category.Get(provider);
                ObjectCache.Insert(cacheName, find);
            }
            return find;
        }

        public static lb_category Get(IDbProvider provider, int id) {
            return Get(provider).FirstOrDefault(cate => cate.id == id);
        }

        public static void Update(IDbProvider provider, lb_category category) {
            ProviderManager.Factory.Category.Update(provider, category);
            Remove();
        }

        public static void Update(IDbProvider provider, lb_category[] categories) {
            foreach (lb_category category in categories) {
                ProviderManager.Factory.Category.Update(provider, category);
            }
            Remove();
        }

        public static void Delete(IDbProvider provider, int id) {
            provider.BeginTransaction();
            try {
                lb_category category = ProviderManager.Factory.Category.Get(provider, id);
                //判断是否为内部分类,否则删除该分类下的所有blog,以及blog的所有评论,track,tags,archive信息及发布用户的该参数信息
                if (!category.isurl) {
                    IList<lb_blog> blogList = ProviderManager.Factory.Blog.GetFromCategory(provider, id);
                    int trackNum = 0;
                    int commentNum = 0;
                    foreach (lb_blog blog in blogList) {
                        ProviderManager.Factory.Blog.Delete(provider, blog.id);
                        ProviderManager.Factory.Comment.DeleteFromBlogID(provider, blog.id);
                        ProviderManager.Factory.Track.DeleteFromBlogID(provider, blog.id);
                        trackNum += ProviderManager.Factory.Track.CountFromBlogID(provider, blog.id);
                        commentNum += ProviderManager.Factory.Comment.Count(provider, blog.id, CommentState.None);
                        lb_archive archive = Archive.Get(provider).Single(ar => ar.year == blog.posttime.Year && ar.month == blog.posttime.Month);
                        archive.num--;
                        if (archive.num > 0) {
                            ProviderManager.Factory.Archive.Update(provider, archive);
                        } else {
                            ProviderManager.Factory.Archive.Delete(provider, archive.id);
                        }
                        lb_user user = ProviderManager.Factory.User.Get(provider, blog.postuser);
                        user.postnum--;
                        ProviderManager.Factory.User.Update(provider, user);
                        string[] tags = blog.tags.Split(',');
                        foreach (string tag in tags) {
                            if (tag.Length > 0) {
                                lb_tag t = ProviderManager.Factory.Tag.Get(provider, tag);
                                t.num--;
                                if (t.num > 0)
                                    ProviderManager.Factory.Tag.Delete(provider, t.id);
                                else
                                    ProviderManager.Factory.Tag.Update(provider, t);
                            }
                        }
                    }
                    lb_state state = State.Get(provider);
                    state.blognum -= blogList.Count;
                    state.commentnum -= commentNum;
                    state.tracknum -= trackNum;
                }
                ProviderManager.Factory.Category.Delete(provider, id);
                provider.Commit();
            } catch (Exception e) {
                provider.Rollback();
                throw new Exception("删除该分类错误.", e);
            }
            Remove();
        }

        public static void Insert(IDbProvider provider, lb_category category) {
            ProviderManager.Factory.Category.Insert(provider, category);
            Remove();
        }

        public static void Remove() {
            ObjectCache.Remove(cacheName);
        }
    }
}
